#include "PacketQueue.h"
#include "SpdLog.h"

AVPacket gFlushPacket;

bool PacketQueue::m_FlashPktInit = false;

PacketQueue::PacketQueue()
{
	m_Queue.clear();
	m_NBPackets = 0;
	m_Size = 0;
	m_Duration = 0;
	m_AbortRequest = false;
	m_Serial = 0;
	recycle_count = 0;
	alloc_count = 0;
	is_buffer_indicator = 0;
	if(!m_FlashPktInit) {
		m_FlashPktInit = true;
		av_init_packet(&gFlushPacket);
		gFlushPacket.data = (uint8_t *)&gFlushPacket;
	}
}

PacketQueue::~PacketQueue()
{
	m_Queue.clear();
}

void PacketQueue::addFlushPkt()
{
	add(gFlushPacket);
}

bool PacketQueue::isFlushPkt(AVPacket &apkt)
{
	return apkt.data == (unsigned char*)&gFlushPacket;
}

void PacketQueue::add(AVPacket &apkt)
{
	AutoLock lock(&m_Cond);
	Packet pkt;
    if(isFlushPkt(apkt))
        m_Serial++;
    pkt.serial = m_Serial;
    pkt.pkt = apkt;
	m_NBPackets++;
	m_Size += apkt.size;
	m_Duration += apkt.duration;
	m_Queue.push_back(pkt);
	notify();
}

int PacketQueue::get(AVPacket &apkt, int &serial)
{
	int ret = 0;
	Packet pkt;
	while(true) {
		if (m_AbortRequest) {
	        ret = -1;
	        break;
	    }
		//wait until pkt is received
		if(isEmpty())
			wait();
		//read pkt
		if(isEmpty())
			continue;
		
		AutoLock lock(&m_Cond);
		pkt = m_Queue[0];
		m_NBPackets--;
		m_Size -= pkt.pkt.size;
		m_Duration -= pkt.pkt.duration;
		apkt = pkt.pkt;
		serial = pkt.serial;
		if(!isEmpty())
			m_Queue.erase(m_Queue.begin());
		
		break;
	}
	return ret;
}